package com.xuecheng.order.config;

import com.alibaba.fastjson.JSON;
import com.xuecheng.messagesdk.model.po.MqMessage;
import com.xuecheng.messagesdk.service.MqMessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * rabbitmq配置类
 */
@Slf4j
@Configuration
public class PayNotifyConfig implements ApplicationContextAware {
    //交换机
    public static final String PAYNOTIFY_EXCHANGE_FANOUT = "paynotify_exchange_fanout";
    //支付结果通知消息类型
    public static final String MESSAGE_TYPE = "payresult_notify";
    //支付通知队列
    public static final String PAYNOTIFY_QUEUE = "paynotify_queue";

    //声明交换机，且持久化
    @Bean(PAYNOTIFY_EXCHANGE_FANOUT)
    public FanoutExchange paynotify_exchange_fanout(){
        return new FanoutExchange(PAYNOTIFY_EXCHANGE_FANOUT,true,false);
    }

    //支付通知队列，且持久化
    @Bean(PAYNOTIFY_QUEUE)
    public Queue course_publish_queue(){
        return QueueBuilder.durable(PAYNOTIFY_QUEUE).build();
    }

    //交换机和支付通知队列绑定
    @Bean
    public Binding binding_course_publish_queue(@Qualifier(PAYNOTIFY_QUEUE) Queue queue,
            @Qualifier(PAYNOTIFY_EXCHANGE_FANOUT) FanoutExchange exchange){
        return BindingBuilder.bind(queue).to(exchange);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        /*
        * 下面是采用return-callback的机制保证消息从交换机到队列的消息可靠性
        * */
        //获取RabbitTemplate
        RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);
        //消息处理service
        MqMessageService mqMessageService = applicationContext.getBean(MqMessageService.class);
        //设置ReturnCallback
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback(){
            @Override
            public void returnedMessage(Message message,int replyCode,String replyText,
                                        String exchange, String routingKey) {
                //投递失败，记录日志
                log.info("消息发送失败，应答码{}，原因{}，交换机{}，路由键{}，消息{}",replyCode,replyText,
                        exchange,routingKey,message);
                MqMessage mqMessage = JSON.parseObject(message.toString(),MqMessage.class);
                //将消息添加到消息表
                mqMessageService.addMessage(mqMessage.getMessageType(),mqMessage.getBusinessKey1(),
                        mqMessage.getBusinessKey2(),mqMessage.getBusinessKey3());
            }
        });
//        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
//            // 投递失败，记录日志
//            log.info("消息发送失败，应答码{}，原因{}，交换机{}，路由键{},消息{}",
//                    replyCode, replyText, exchange, routingKey, message.toString());
//            MqMessage mqMessage = JSON.parseObject(message.toString(), MqMessage.class);
//            //将消息再添加到消息表
//            mqMessageService.addMessage(mqMessage.getMessageType(),mqMessage.getBusinessKey1(),
//                    mqMessage.getBusinessKey2(),mqMessage.getBusinessKey3());
//        });
    }
}
